/**
 * Created on Apr 20, 2000
 */
package jvs.core.ftp;


import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Properties;

import jvs.core.Lifecycle;
import jvs.vfs.FileSystem;
import x.java.io.File;

/**
 * @author qiangli
 * 
 */

public class FtpServer implements Lifecycle, Runnable {
	private boolean running = false;
	private static int serverId = 0;
	private int instanceId = 0;

	private int port = 21;

	private String root;
	private String publicRoot;

	private Thread server = null;

	public FtpServer() {
	}

	public void run() {
		ServerSocket ss = null;
		try {
			ss = new ServerSocket(port);
		} catch (Exception e) {
			e.printStackTrace();
			System.exit(1);
		}
		serverId++;
		while (running) {
			try {
				log("JAVA FTP Server by Li Qiang. [" + serverId + ":"
						+ (++instanceId) + "]");
				Socket s = ss.accept();
				String nroot = getAuthRoot(s);
				log("remote address: "+s.getRemoteSocketAddress()+" root: "+nroot);
				if (nroot != null) {
					PI pi = new PI(s, nroot);
					new Thread(pi).start();
				} else {
					// not authorized
					s.close();
				}
			} catch (Exception e) {
				e.printStackTrace();
				//System.exit(1);
			}
		}
		try {
			ss.close();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	/**
	 * @return If pre-authorized, 
	 *  /public for remote host 
	 *  / for localhost
	 */
	private String getAuthRoot(Socket s) {
		try {

			InetAddress ra = s.getInetAddress();
			String raddr = ra.getHostAddress();

			System.out.println("raddr: " + raddr);

			// is local
			String laddr = InetAddress.getLocalHost().getHostAddress();
			System.out.println("laddr " + laddr);

			String lnet = laddr.substring(0, laddr.lastIndexOf("."));
			System.out.print("ln " + lnet);

			if (raddr.equals("127.0.0.1") || raddr.equals(laddr)) {
				return root;
			}
			
			return publicRoot;
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}

	public void init(Properties attrs) {
		root = null;
		publicRoot = null;
		//
		try {
			if (attrs != null) {
				port = Integer.parseInt(attrs.getProperty("ftp.port", "21"));
				File fsroot = FileSystem.getFileSystem().getRoot();
				if (getBoolean(attrs,"ftp.option.local")) {
					root = fsroot.toString();
				}
				if (getBoolean(attrs, "ftp.option.public")) {
					publicRoot = new x.java.io.File(fsroot, "public")
							.toString();
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	private boolean getBoolean(Properties p, String key) {
		try {
			Object o = p.get(key);
			if (o == null) {
				return false;
			}
			return Boolean.parseBoolean(o.toString());
		} catch (Exception e) {
			e.printStackTrace();
		}
		return false;
	}

	public void shutdown() throws Exception {
		running = false;
		server.interrupt();
	}

	public void startup() throws Exception {
		running = true;
		server = new Thread(this);
		server.start();
	}

	private void log(String s) {
		System.out.println("FtpServer: " + s);
	}

	public static void main(String[] args) {
		String uri = new java.io.File("c:/temp").toURI().toString();
		java.lang.System.setProperty("jvs.rootfs", uri);
		java.lang.System.setProperty("jvs.debug", "trace");
		FileSystem.getFileSystem().boot();
		try {
			FtpServer s = new FtpServer();
			Properties prop = new Properties();
			prop.put("ftp.option.local", "true");
			s.init(prop);
			s.startup();
			Thread.sleep(Integer.MAX_VALUE);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}